/*
Automatic clinic tests using a robot arm.
Copyright (C) 2010  CIC-CPC, CHU Gabriel Montpied
All other trademarks, logos and copyrights are the property
of their respective owners.

This file is part of cpc-painbot.

cpc-painbot is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

cpc-painbot is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with cpc-painbot.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "operation/upanddown.h"
#include "ui_upanddown.h"

#include <QMessageBox>
#include <QProgressDialog>
#include <QFile>

#include "seuil/determination.h"
#include "seuil/methode/upanddown.h"
#include "stimulation/stimulateur.h"

//! \todo Deconnecter depuis l'ancien stimulateur/ancienne méthode.
//! Tout déconnecter au début ?
UpAndDown::UpAndDown(QWidget *parent) :
    QWizardPage(parent),
    ui(new Ui::UpAndDown),
    attente_(new QProgressDialog(this)),
    determination_(0)

{
    setPixmap(QWizard::WatermarkPixmap, QPixmap(":/illustrations/upanddown"));
    ui->setupUi(this);

    attente_->setModal(true);
    attente_->setWindowTitle(tr("Stimulation"));
    attente_->setLabelText(tr("Stimulation en cours..."));
    attente_->setMaximum(0);
    attente_->setValue(-1);

    connect(attente_, SIGNAL(accepted()), this, SLOT(demanderDouleur()));

    setCommitPage(true);
}

UpAndDown::~UpAndDown()
{
    delete ui;
}

void UpAndDown::initializePage()
{
    qDebug() << "Up and Down : initializePage()";
    setButtonText(QWizard::CommitButton, tr("Fin de Stimulation"));

    // Création de la méthode.
    if ( determination_->methode() != 0 )
        determination_->methode()->deleteLater();

    seuil::methode::UpAndDown *methode = new seuil::methode::UpAndDown(determination_);
    determination_->setMethode(methode);

    // Chargement du Rack.
    QFile rack(field("stimulateur.rack").toString());
    rack.open(QIODevice::ReadOnly | QIODevice::Text);
    methode->setRack(Rack::charger(&rack, methode));

    // Gestion des signaux issus de la méthode.
    connect(methode, SIGNAL(phaseChangee(int)), this, SLOT(changementPhase(int)));
    connect(methode, SIGNAL(erreur(QString)), this, SLOT(erreur(QString)));
    connect(methode, SIGNAL(termineeChange(bool)), this, SLOT(terminer(bool)));
    connect(methode, SIGNAL(termineeChange(bool)), this, SIGNAL(completeChanged()));
    connect(methode, SIGNAL(termineeChange(bool)), ui->stimulerPushButton, SLOT(setDisabled(bool)));

    // Préparation.
    determination_->preparer();

    // Gestion du stimulateur.
    Stimulateur *stimulateur = determination_->stimulateur();
    attente_->disconnect(stimulateur);
    stimulateur->disconnect(attente_);
    connect(stimulateur, SIGNAL(started()), attente_, SLOT(show()));
    connect(stimulateur, SIGNAL(finished()), attente_, SLOT(accept()));
    connect(attente_, SIGNAL(canceled()), stimulateur, SLOT(stop()));

    // action de stimulation.
    ui->stimulerPushButton->disconnect(stimulateur);
    connect(ui->stimulerPushButton, SIGNAL(clicked()), stimulateur, SLOT(stimuler()));

    // Configuration de la Zone.
    //! \todo Configurer à la page de récapitulatif ?
    stimulateur->zone()->setRayonMax(field("zone.rayonMax").toDouble());
    stimulateur->zone()->setRayonMin(field("zone.rayonMin").toDouble());
}

bool UpAndDown::isComplete() const
{
    return determination_->methode()->isTerminee();
}

void UpAndDown::changementPhase(int phase)
{
    Q_ASSERT(phase >= 0);

    switch (phase) {
    case seuil::methode::UpAndDown::Up :
            ui->upImageLabel->setPixmap(QPixmap(":/images/attente"));
            ui->confirmerImageLabel->setPixmap(QPixmap(":/images/attente"));
            ui->downImageLabel->setPixmap(QPixmap(":/images/attente"));
            ui->confirmerImageLabel->setEnabled(false);
            ui->confirmerLabel->setEnabled(false);
            ui->downImageLabel->setEnabled(false);
            ui->downLabel->setEnabled(false);
            break;

        case seuil::methode::UpAndDown::Confirmation :
            ui->upImageLabel->setPixmap(QPixmap(":/images/fait"));
            ui->upLabel->setEnabled(false);
            ui->confirmerImageLabel->setEnabled(true);
            ui->confirmerLabel->setEnabled(true);
            break;

        case seuil::methode::UpAndDown::Down :
            ui->confirmerImageLabel->setPixmap(QPixmap(":/images/fait"));
            ui->confirmerLabel->setEnabled(false);
            ui->downImageLabel->setEnabled(true);
            ui->downLabel->setEnabled(true);
            break;
    }
}

void UpAndDown::terminer(bool ok)
{
    if ( ok )
        ui->downImageLabel->setPixmap(QPixmap(":/images/fait"));
}

void UpAndDown::erreur(const QString &desc)
{
    if ( desc == "confirmation" ) {
        ui->confirmerImageLabel->setPixmap(QPixmap(":/images/erreur"));
        ui->downImageLabel->setPixmap(QPixmap(":/images/erreur"));
    }
}

void UpAndDown::demanderDouleur()
{
    QMessageBox::StandardButton douleur =
            QMessageBox::question(0, tr("Douleur"), tr("Y a-t-il eu douleur ?"),
                                  QMessageBox::Yes | QMessageBox::No);

    determination_->methode()->douleur(douleur == QMessageBox::Yes);
}

void UpAndDown::changeEvent(QEvent *e)
{
    QWizardPage::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}
